﻿using System;
using System.Collections.Generic;
using System.Text;
using AjaxPro;
using System.Reflection;

namespace NExt.Serialization.AjaxPro.Conversion
{
    public class ExtJavaScriptConvertor : IJavaScriptConverter
    {
        public ExtJavaScriptConvertor()
        {
            m_AllowInheritance = true;
            m_serializableTypes = new Type[] { typeof(global::NExt.Core.Model.Base.Component) };
        }

        public override void Serialize(object o, StringBuilder sb)
        {
            try
            {
                SerializeCustomObject(o, sb);
            }
            catch (Exception ex)
            {
            }
        }

        internal static void SerializeCustomObject(object objectValue, StringBuilder sb)
        {
            bool b;
            sb.Append('{');
            Type objectType = objectValue.GetType();
            IEnumerable<PropertyInfo> propertyInfos = GetPropertyInfos(objectType);
            IEnumerable<FieldInfo> fieldInfos = GetFieldInfos(objectType);

            b = SerilizationHelper.SerializeVariables(objectValue, sb, fieldInfos);
            //b = SerializeFields(objectValue, sb, b, objectType);
            b = SerilizationHelper.SerializeProperties(objectValue, sb, b, propertyInfos);
            b = SerializeExtendedProperties(objectValue, sb, b, objectType);
            //b = SerializeAnonymousConfig(objectValue, sb, b, objectType);

            sb.Append('}');
        }

        internal static bool SerializeExtendedProperties(object objectValue, StringBuilder sb, bool b, Type objectType)
        {
            object extended = ((global::NExt.Core.Model.Base.Component)objectValue).extended;
            if (!SerilizationHelper.IsSerializableValue(extended))
                return b;

            Type extendedType = extended.GetType();
            IEnumerable<PropertyInfo> propertyInfos = GetPropertyInfos(extendedType);
            b = SerilizationHelper.SerializeProperties(extended, sb, b, propertyInfos);
            return b;
        }

        private static IEnumerable<FieldInfo> GetFieldInfos(Type objectType)
        {
            return objectType.GetFields(BindingFlags.Public | BindingFlags.Instance);
        }

        private static IEnumerable<PropertyInfo> GetPropertyInfos(Type objectType)
        {
            return objectType.GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance);
        }
    }
}
